package com.fysports.web.config.freemarker;

import com.fysports.web.kit.cache.EHCacheFactory;
import freemarker.core.Environment;
import freemarker.template.*;

import java.io.IOException;
import java.io.Writer;
import java.util.Map;


/**
 * 自定义freemarker指令，用来读取缓存信息
 * 包括系统基础配置，常用配置
 * Created by konbluesky
 * Date : 14-8-21 下午3:31
 * Project : JdmData_WebServer
 */
public class CacheDirective implements TemplateDirectiveModel {
    @Override public void execute(Environment environment, Map map, TemplateModel[] templateModels,
            TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException {
        /* 1.验证参数是否有效 */
        if (map.isEmpty()) {
            throw new TemplateModelException("This directive doesn't allow parameters.");
        }
        /* 2.获取对象*/
        Object obj = null;
        String key = null;
        String cachename = null;
        if ((map.containsKey("cachename") && map.get("cachename") != null) && (map.containsKey("key")
                && map.get("key") != null)) {
            cachename = ((SimpleScalar) map.get("cachename")).getAsString();
            key = ((SimpleScalar) map.get("key")).getAsString();
            obj = EHCacheFactory.getInstance().get(cachename, key);
        }

        if (obj == null) {//如缓存对象不存在，构建错误提示
            StringBuilder sb = new StringBuilder();
            sb.append("<font color=\"red\">缓存对象读取失败。</font>");
            sb.append("<br>cachename:").append(cachename);
            sb.append("<br>key:").append(key);
            /*将错误信息写入writer流*/
            templateDirectiveBody.render(new ErrorMessageFilterWriter(environment.getOut(), sb.toString()));
            return;
        }
        else {//存在
            /*
            * 3.包装缓存对象
            * 在freemarker指令传输过程中 需要以TemplateModel对象为基类，故对象需要经过包装后
            * 放入env
            * */
            TemplateModel tm = WrappingTemplateModel.getDefaultObjectWrapper().wrap(obj);
            environment.setVariable("obj", tm);
            templateDirectiveBody.render(environment.getOut());
        }

    }


    /**
     * 将错误信息写入writer
     */
    private static class ErrorMessageFilterWriter extends Writer {
        private final Writer _out;


        ErrorMessageFilterWriter(Writer out, String msg) {
            this._out = out;
            if (msg != null && msg.length() > 0) {
                try {
                    _out.append(msg);
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


        public void write(char[] cbuf, int off, int len) throws IOException {
            _out.write(cbuf);
        }


        public void flush() throws IOException {
            _out.flush();
        }


        public void close() throws IOException {
            _out.close();
        }
    }
}
